package com.ybb.vue.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ybb.vue.common.Result;
import com.ybb.vue.common.exception.GlobalExceptionHandler;
import com.ybb.vue.common.exception.MyException;
import com.ybb.vue.domain.dto.ApprovalDto;
import com.ybb.vue.entity.Approval;
import com.ybb.vue.entity.GoodsIn;
import com.ybb.vue.entity.GoodsInventory;
import com.ybb.vue.entity.GoodsOut;
import com.ybb.vue.mapper.GoodsInMapper;
import com.ybb.vue.mapper.GoodsInventoryMapper;
import com.ybb.vue.mapper.GoodsOutMapper;
import com.ybb.vue.service.ApprovalService;
import com.ybb.vue.mapper.ApprovalMapper;
import com.ybb.vue.service.GoodsInService;
import com.ybb.vue.service.GoodsInventoryService;
import com.ybb.vue.service.GoodsOutService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
* @author apple
* @description 针对表【approval(审核信息表)】的数据库操作Service实现
* @createDate 2023-04-04 16:49:00
*/
@Service
public class ApprovalServiceImpl extends ServiceImpl<ApprovalMapper, Approval>
implements ApprovalService{

    @Autowired
    private ApprovalMapper approvalMapper;

    @Lazy
    @Autowired
    private GoodsInService goodsInService;

    @Autowired
    private GoodsInMapper goodsInMapper;

    @Lazy
    @Autowired
    private GoodsOutService goodsOutService;

    @Autowired
    private GoodsOutMapper goodsOutMapper;

    @Autowired
    private GoodsInventoryService goodsInventoryService;

    @Autowired
    private GoodsInventoryMapper goodsInventoryMapper;

    @Override
    @Transactional
    public Result approval(ApprovalDto approvalDto) {
        Approval approval = approvalMapper.selectOne(new QueryWrapper<Approval>().lambda().eq(Approval::getSubjectId, approvalDto.getSubjectId()).eq(Approval::getSubjectSource, approvalDto.getSubjectSource()));
        if (approval == null) {
            return Result.error("-1", "未查询到审核记录");
        }
        String person = SecurityContextHolder.getContext().getAuthentication().getName();
        // 改变审核表
        BeanUtils.copyProperties(approvalDto, approval);
        approval.setApprovalBy(person);
        approval.setApprovalTime(new Date());
        this.updateById(approval);
        // 通过
        if ("1".equals(approval.getApprovalStatus())) {
            // 入库-新增
            if ("INA".equals(approval.getSubjectSource())) {
                // 改变入库表
                GoodsIn goodsIn = goodsInMapper.selectById(approval.getSubjectId());
                goodsIn.setInStatus(approvalDto.getApprovalStatus());
                goodsIn.setInTime(new Date());
                goodsIn.setHandler(person);
                goodsInService.updateById(goodsIn);
                // 加入物资清单
                GoodsInventory goodsInventory = new GoodsInventory();
                BeanUtils.copyProperties(goodsIn, goodsInventory);
                goodsInventory.setStock(goodsIn.getInNumber());
                goodsInventoryService.save(goodsInventory);
            }
            // 入库-添加
            if ("INC".equals(approval.getSubjectSource())) {
                // 改变入库表
                GoodsIn goodsIn = goodsInMapper.selectById(approval.getSubjectId());
                goodsIn.setInStatus(approvalDto.getApprovalStatus());
                goodsIn.setInTime(new Date());
                goodsIn.setHandler(person);
                goodsInService.updateById(goodsIn);
                // 在清单中找到此类物资
                GoodsInventory goodsInventoryHistory = goodsInventoryMapper.selectOne(new QueryWrapper<GoodsInventory>().lambda().eq(GoodsInventory::getGoodsType, goodsIn.getGoodsType()).eq(GoodsInventory::getGoodsName, goodsIn.getGoodsName()));
                // 加入物资清单
                // 库存为 入库+原先库存
                goodsInventoryHistory.setStock(goodsIn.getInNumber() + goodsInventoryHistory.getStock());
                goodsInventoryService.updateById(goodsInventoryHistory);
            }
            // 出库
            if ("OUT".equals(approval.getSubjectSource())) {
                GoodsOut goodsOut = goodsOutMapper.selectById(approval.getSubjectId());
                // 在清单中找到此类物资
                GoodsInventory goodsInventoryHistory = goodsInventoryMapper.selectOne(new QueryWrapper<GoodsInventory>().lambda().eq(GoodsInventory::getGoodsType, goodsOut.getGoodsType()).eq(GoodsInventory::getGoodsName, goodsOut.getGoodsName()));
                if (goodsInventoryHistory.getStock() < goodsOut.getOutNumber()) {
                    throw new MyException("库存不足");
                }
                // 改变出库表
                goodsOut.setOutStatus(approval.getApprovalStatus());
                goodsOut.setOutTime(new Date());
                goodsOut.setHandler(person);
                goodsOutService.updateById(goodsOut);
                // 改变清单表
                goodsInventoryHistory.setStock(goodsInventoryHistory.getStock() - goodsOut.getOutNumber());
                goodsInventoryService.updateById(goodsInventoryHistory);
            }
        }
        // 驳回
        if ("2".equals(approval.getApprovalStatus())) {
            // 入库
            if ("INA".equals(approval.getSubjectSource()) || "INC".equals(approval.getSubjectSource())) {
                // 改变入库表
                GoodsIn goodsIn = goodsInMapper.selectById(approval.getSubjectId());
                goodsIn.setInStatus(approvalDto.getApprovalStatus());
                goodsIn.setInTime(new Date());
                goodsIn.setHandler(person);
                goodsInService.updateById(goodsIn);
            }
            // 出库
            if ("OUT".equals(approval.getSubjectSource())) {
                GoodsOut goodsOut = goodsOutMapper.selectById(approval.getSubjectId());
                // 改变出库表
                goodsOut.setOutStatus(approval.getApprovalStatus());
                goodsOut.setOutTime(new Date());
                goodsOut.setHandler(person);
                goodsOutService.updateById(goodsOut);
            }
        }
        return Result.success();
    }
}
